import 'package:built_collection/built_collection.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_item.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_one_time_purchased_item_info.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_one_time_purchased_item_transaction.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_purchased_item_info.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_transaction.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_purchased_subscription_info.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_purchased_subscription_transaction.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_one_time_purchased_item_from_internal_one.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_subscription_from_internal_one.dart';

abstract class CreateApiGooglePlayPurchasedItemsFromInternalOnes {
  BuiltList<ApiGooglePlayPurchasedItem> call({
    required BuiltList<GooglePlayPurchasedItemInfo> purchasedItemInfos,
    required BuiltList<GooglePlayTransaction> purchasedItemTransactions,
  });
}

class CreateApiGooglePlayPurchasedItemsFromInternalOnesImpl
    implements CreateApiGooglePlayPurchasedItemsFromInternalOnes {
  const CreateApiGooglePlayPurchasedItemsFromInternalOnesImpl({
    required CreateApiGooglePlayPurchasedSubscriptionFromInternalOne
        createApiGooglePlayPurchasedSubscriptionFromInternalOne,
    required CreateApiGooglePlayOneTimePurchasedItemFromInternalOne
        createApiGooglePlayOneTimePurchasedItemFromInternalOne,
  })  : _createApiGooglePlayPurchasedSubscriptionFromInternalOne =
            createApiGooglePlayPurchasedSubscriptionFromInternalOne,
        _createApiGooglePlayOneTimePurchasedItemFromInternalOne =
            createApiGooglePlayOneTimePurchasedItemFromInternalOne;

  final CreateApiGooglePlayPurchasedSubscriptionFromInternalOne
      _createApiGooglePlayPurchasedSubscriptionFromInternalOne;
  final CreateApiGooglePlayOneTimePurchasedItemFromInternalOne
      _createApiGooglePlayOneTimePurchasedItemFromInternalOne;

  @override
  BuiltList<ApiGooglePlayPurchasedItem> call({
    required BuiltList<GooglePlayPurchasedItemInfo> purchasedItemInfos,
    required BuiltList<GooglePlayTransaction> purchasedItemTransactions,
  }) {
    final transactionMap = <String, List<GooglePlayTransaction>>{};

    for (final transaction in purchasedItemTransactions) {
      transactionMap[transaction.purchaseToken] ??= [];
      transactionMap[transaction.purchaseToken]!.add(transaction);
    }

    final apiPurchasedItem = <ApiGooglePlayPurchasedItem>[];

    for (final purchasedItemInfo in purchasedItemInfos) {
      if (purchasedItemInfo is GooglePlayOneTimePurchasedItemInfo) {
        final oneTimePurchasedItemInfo = purchasedItemInfo;
        final transactions = transactionMap[oneTimePurchasedItemInfo.purchaseToken];

        if (transactions != null) {
          final apiOneTimePurchasedItem = _createApiGooglePlayOneTimePurchasedItemFromInternalOne(
            oneTimePurchasedItemInfo: oneTimePurchasedItemInfo,
            oneTimePurchasedItemTransaction:
                transactions.first as GooglePlayOneTimePurchasedItemTransaction,
          );

          apiPurchasedItem.add(apiOneTimePurchasedItem);
        }
      } else if (purchasedItemInfo is GooglePlayPurchasedSubscriptionInfo) {
        final purchasedSubscriptionInfo = purchasedItemInfo;
        final transactions = transactionMap[purchasedSubscriptionInfo.purchaseToken];

        if (transactions != null) {
          final purchasedSubscriptionTransactions =
              BuiltList<GooglePlayPurchasedSubscriptionTransaction>(transactions);

          final apiPurchasedSubscription = _createApiGooglePlayPurchasedSubscriptionFromInternalOne(
            purchasedSubscriptionInfo: purchasedSubscriptionInfo,
            purchasedSubscriptionTransactions: purchasedSubscriptionTransactions,
          );

          apiPurchasedItem.add(apiPurchasedSubscription);
        }
      }
    }

    return apiPurchasedItem.toBuiltList();
  }
}
